﻿using ACC.Data.Entities.Common;
using ACC.Data.Entities.Mes;
using ACC.Extensions.ClientBusiness;
using ACC.Extensions.ClientBusiness.PLC;
using ACC.Extensions.Entities;
using ACC.Extensions.PCClient.BaseWindow;
using ACC.Extensions.PCClient.Helper;
using ACC.Extensions.PCClient.UserControls;
using ACC.Extensions.Utilities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ACC.Extensions.PCClient.View
{
    /// <summary>
    /// Interaction logic for ACCPcClientWnd.xaml
    /// </summary>
    public partial class ACCPcClientWnd : BaseCustomWindow
    {
        private object _lockObj = new object();
        //状态栏检测线程
        private Thread _clientThread;
        //状态栏检测线程是否在运行
        private bool bIsRunning = false;
        BarcodeInfo selectedBarcode = null;
        //条码列表
        private List<BarcodeCountControl> _barcodeCountCtrlList = new List<BarcodeCountControl>();
        private List<ClientProcData> _CastingLoadData = new List<ClientProcData>();
        private List<ReaderCodeDetail> listBarcodeDetail = new List<ReaderCodeDetail>();
        private ComScanner comScanner = null;

        public ACCPcClientWnd()
        {
            InitializeComponent();
            //从配置文件读取端口
            inAccPort = AppConfigHelper.GetAppSettings("SocketPort").ToInt();
            debugMode = AppConfigHelper.GetAppSettings("DebugMode").ToString();
        }

        private void BaseCustomWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //禁用所有控件
            DisableUIControls();
            //初始化条码列表列名
            InitDataGridColumn();
            //初始化窗口
            InitUIDisplayItem();
            //加载本地保存的条码
            LoadDataGridBarcode();
            //注册自定义事件
            RegistCustomEvent();
            //创建AccProcess对象，连接到WCF的
            CreateAccProcess();
            //创建Socketserver监听ACC和PLC的连接
            CreateAccSocketServer(this.lvwMsgDevice);

            if (UISession.ClientSetting.COM_Enable)
            {
                comScanner = new ComScanner();
                comScanner.Init(UISession.ClientSetting.COM_PortName,
                    UISession.ClientSetting.COM_BaudRate,
                    UISession.ClientSetting.COM_Parity,
                    UISession.ClientSetting.COM_DataBits,
                    UISession.ClientSetting.COM_StopBits);
                comScanner.OnBCRead += comScanner_OnBCRead;
                comScanner.OnBCStatusChanged +=comScanner_OnBCStatusChanged;
            }

            //去掉窗体顶部栏
            this.UseNoneWindowStyle = true;
            //忽略任务栏最大化
            this.IgnoreTaskbarOnMaximize = true;
            //窗体初始最大化
            this.WindowState = WindowState.Maximized;

            //加载操作手册
            //LoadHelp();
        }

        private void comScanner_OnBCRead(string bc)
        {
            //显示扫描信息
            //ShowMessage(this.lvMessage, String.Format(LanguageHelper.LoadStringFromResource("MSG_SCAN_TRAYNO"), bc), false);
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.txtBarcode.Text = bc;
                HandleScanMaterial(); 
                
            }));
        }

        private void comScanner_OnBCStatusChanged(bool connect)
        {
            //ShowMessage(this.lvMessage, String.Format(LanguageHelper.LoadStringFromResource("MSG_SCAN_TRAYNO"), connect), false);
            UpdateDeviceStatus(LanguageHelper.LoadStringFromResource("SCANNER"), connect);
        }

        private void LoadHelp()
        {
            //获取操作手册目录
            string helpFullName = System.AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["HelpFolder"].ToString();
            //本地目录存在则加载
            if (Directory.Exists(helpFullName))
            {
                DirectoryInfo TheFolder = new DirectoryInfo(helpFullName);
                foreach (FileInfo NextFile in TheFolder.GetFiles())
                {
                    if (IsVideoType(NextFile.Name) || IsImageType(NextFile.Name) || IsPdfType(NextFile.Name))
                    {
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            CheckBox chk = new CheckBox();
                            chk.Margin = new Thickness(5);
                            chk.FontSize = 28;
                            chk.Tag = NextFile.Name;
                            chk.Content = NextFile.Name;

                            chk.Checked += Chk_HelpChecked;
                            chk.Unchecked += Chk_Unchecked;
                            pnlSopVideoList.Children.Add(chk);
                        }));
                    }
                }
            }
        }

        void Chk_HelpChecked(object sender, RoutedEventArgs e)
        {
            var chk = sender as CheckBox;

            if (chk != null)
            {
                foreach (CheckBox child in pnlSopVideoList.Children)
                {
                    if ((bool)child.IsChecked && child.Tag != chk.Tag)
                        child.IsChecked = false;
                }

                ResetSopPlayer(ConfigurationManager.AppSettings["HelpFolder"].ToString(), chk);
            }
        }

        private void BaseCustomWindow_Activated(object sender, EventArgs e)
        {
            UISession.IsWndActivated = this.IsActive;
        }

        private void BaseCustomWindow_Deactivated(object sender, EventArgs e)
        {
            UISession.IsWndActivated = this.IsActive;
        }

        //单击“设备消息”按钮
        private void btnMsgDevice_Click(object sender, RoutedEventArgs e)
        {
            this.flyMessage.IsOpen = !this.flyMessage.IsOpen;
        }

        //单击“报警复位”按钮
        private void btnAlarmRest_Click(object sender, RoutedEventArgs e)
        {
            ctrNavBar.StopAlarm();
            //plcProcess.ResetAlarm();//复位PLC报警地址位
        }

        //单击“在线返修”按钮
        private void btnOnlineRepair_Click(object sender, RoutedEventArgs e)
        {
            if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
            {
                btnLogin_Click(null, null);
            }
            else
            {
                ResultWithReasonWnd Wnd = new ResultWithReasonWnd(selectedBarcode.Barcode, false, GetStatusBitList(UISession.CurrentPartType));
                var dialogResult = Wnd.ShowDialog();
                if (dialogResult.HasValue && dialogResult.Value)
                {
                    Decide(GetDataGridListBarcodeInfo().Select(p => p.Barcode).ToList(), 2, Wnd.UnloadData);
                }
            }
        }

        //单击“不合格NOK”按钮
        private void btnNOK_Click(object sender, RoutedEventArgs e)
        {
            if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
            {
                btnLogin_Click(null, null);
            }
            else
            {
                ResultWithReasonWnd Wnd = new ResultWithReasonWnd(selectedBarcode.Barcode, false, GetStatusBitList(UISession.CurrentPartType));
                var dialogResult = Wnd.ShowDialog();
                if (dialogResult.HasValue && dialogResult.Value)
                {
                    isNG = true;
                    unloadNGData = Wnd.UnloadData;
                    //if (unloadRequested)
                    //{
                    //    Decide(GetDataGridListBarcodeInfo().Select(p => p.Barcode).ToList(), 0, Wnd.UnloadData);
                    //}
                    //else
                    //{
                    //    decided = false;
                    //    unloadNGData = Wnd.UnloadData;
                    //    ShowMessage(this.lvMessage, string.Format(LanguageHelper.LoadStringFromResource("WAITING_UNLOAD"), "NOK"), false);
                    //}
                }
            }
        }

        //单击“合格OK”按钮
        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
            {
                btnLogin_Click(null, null);
            }
            else
            {
                //if (unloadRequested)
                //    Decide(GetDataGridListBarcodeInfo().Select(p => p.Barcode).ToList(), 1);
                //else
                //{
                isNG = false;
                //    ShowMessage(this.lvMessage, string.Format(LanguageHelper.LoadStringFromResource("WAITING_UNLOAD"), "OK"), false);
                //}
            }
        }

        //判定操作
        private void Decide(List<string> barcodes, int result, UnloadVariable unloadData = null)
        {
            string trayNo = "";
            if (UISession.ClientSetting.UseUnloadPallet)
            {
                trayNo = plcProcess.GetUnloadTrayNo();
            }
            else
            {
                trayNo = plcProcess.GetTrayNo();
            }
            //barcodes.Add(trayNo);
            bool bRes = PcClientUnload(barcodes, result != 1 ? 0 : result, unloadData);
            if (bRes)
            {
                plcProcess.UnloadSuccessfully(result);
            }
            else
            {
                plcProcess.UnloadFailed();
            }
        }

        //判断是否已登录
        //private bool IsLogined()
        //{
        //    if (string.IsNullOrEmpty(this.ctrNavBar.txtOperator.Text) || UISession.CurrentOperator == null)
        //        return false;
        //    return true;
        //}

        //单击“登录”按钮
        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            UserLoginWnd userLoginWnd = new UserLoginWnd();
            var dialogResult = userLoginWnd.ShowDialog();

            string operatorId = string.Empty;
            if (!dialogResult.HasValue || !dialogResult.Value)
            {
                return;
            }
            operatorId = userLoginWnd.OperatorId;

            string msg = String.Empty;
            UISession.CurrentOperator = accProcess.OperatorLogin(operatorId, out msg);
            if (!String.IsNullOrEmpty(msg))
            {
                MessageDialogWnd.ShowDialog("Error", msg);
            }
            else
            {
                this.ctrNavBar.txtOperator.Text = String.Format("{0}({1})", UISession.CurrentOperator.Name, UISession.CurrentOperator.OperatorId);
                RefreshElementState();
            }
        }

        //读取本机配置信息
        private void miClientConfig_Click(object sender, RoutedEventArgs e)
        {
            UserValidateWnd dialogWnd = new UserValidateWnd();
            var dialogResult = dialogWnd.ShowDialog();
            if (!(dialogResult.HasValue && dialogResult.Value))
            {
                return;
            }
            ConfigClientWnd configWnd = new ConfigClientWnd();
            configWnd.ShowDialog();
        }

        //语言切换成中文
        private void miChinese_Click(object sender, RoutedEventArgs e)
        {
            LanguageHelper.SelectChinese();
            //保存语言配置
            AppConfigHelper.UpdateAppSettings("Lang", "cn");
        }

        //语言切换成英文
        private void miEnglish_Click(object sender, RoutedEventArgs e)
        {
            LanguageHelper.SelectEnglish();
            //保存语言配置
            AppConfigHelper.UpdateAppSettings("Lang", "en");
        }

        //关于公司信息
        private void miAbout_Click(object sender, RoutedEventArgs e)
        {
            AboutWnd aboutWnd = new AboutWnd();
            aboutWnd.ShowDialog();
        }

        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.tabControl1.SelectedIndex == 1)
            {
                if (sopMediaPlayer.status == "已暂停")
                    sopMediaPlayer.Ctlcontrols.play();
            }
            else
            {
                sopMediaPlayer.Ctlcontrols.pause();
            }
        }

        #region 工艺文件展示
        //FtpHelper ftp = null;
        void AddSopVideoList(List<MESWI> wis)
        {
            //MESWI temp = new MESWI();
            //temp.wi_filename = "E1B5015D175877EA557E3166C10AB57C.mp4";
            //temp.wi_filepath = "ftp://127.0.0.1";
            //wis.Add(temp);

            //MESWI temp1 = new MESWI();
            //temp1.wi_filename = "How to use MC 3000-20120607 [Compatibility Mode].pdf";
            //temp1.wi_filepath = "ftp://127.0.0.1";
            //wis.Add(temp1);

            //MESWI temp2 = new MESWI();
            //temp2.wi_filename = "微信截图_20181120142244.png";
            //temp2.wi_filepath = "ftp://127.0.0.1";
            //wis.Add(temp2);
            new Thread(new ThreadStart(delegate()
            {
                //Dispatcher.BeginInvoke(new Action(() =>
                //{
                //    if (pnlSopVideoList != null && pnlSopVideoList.Children != null)
                //    { 
                //        pnlSopVideoList.Children.Clear();
                //        LoadHelp();
                //    }
                //}));

                //下载到本地目录
                string SopFolderFullName = System.AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["SopFolder"].ToString();
                //本地目录不存在则创建
                if (!Directory.Exists(SopFolderFullName))
                {
                    Directory.CreateDirectory(SopFolderFullName);
                }

                //if (wis.Count == 0)//网络路径没搜索到文件，就加载本地文件
                //{
                //    LoadLocalFiles(SopFolderFullName);
                //    return;
                //}

                //string ftpServerIP = "127.0.0.1";
                //string mask = "*.*";
                string uid = ConfigurationManager.AppSettings["FTPUser"].ToString();
                string pwd = ConfigurationManager.AppSettings["FTPPwd"].ToString();
                //ftp = new FtpHelper(ftpServerIP, "", uid, pwd);
                //string[] fileNames = ftp.GetFileList(mask);


                foreach (MESWI wi in wis)
                {
                    if (IsVideoType(wi.wi_filename) || IsImageType(wi.wi_filename) || IsPdfType(wi.wi_filename))
                    {
                        //CheckBox chk = null;
                        //Dispatcher.BeginInvoke(new Action(() =>
                        //{
                        //    chk = new CheckBox();
                        //    chk.Margin = new Thickness(5);
                        //    chk.FontSize = 24;
                        //    chk.Tag = wi.wi_filename;
                        //    chk.Content = wi.wi_filename;

                        //    chk.Checked += Chk_Checked;
                        //    chk.Unchecked += Chk_Unchecked;
                        //    pnlSopVideoList.Children.Add(chk);
                        //}));
                        
                        FtpHelper ftp = new FtpHelper(uid, pwd);
                        //获取ftp上文件最后更新时间
                        DateTime dtFtpLast = ftp.GetFileModifyDateTime(wi.wi_filepath + "/" + wi.wi_filename);
                        //获取本地文件最后更新时间
                        DateTime dtLocLast = DateTime.MinValue;
                        bool isExist = File.Exists(SopFolderFullName + "\\" + wi.wi_filename);
                        if (isExist)
                        {
                            FileInfo file = new FileInfo(SopFolderFullName + "\\" + wi.wi_filename);
                            dtLocLast = file.LastWriteTime;
                            if (dtFtpLast > dtLocLast) file.Delete();
                        }
                        if (dtFtpLast > dtLocLast)
                        {
                            //Dispatcher.BeginInvoke(new Action(() =>
                            //{
                            //    chk.IsEnabled = false;
                            //    chk.Content = "..." + chk.Content.ToString();
                            //}));
                            new Thread(new ThreadStart(delegate()
                            {
                                ftp.Download(SopFolderFullName, wi.wi_filename, wi.wi_filepath);
                                //Dispatcher.BeginInvoke(new Action(() =>
                                //{
                                //    chk.Content = chk.Content.ToString().Replace("...", "");
                                //    chk.IsEnabled = true;
                                //}));
                            })).Start();
                        }
                    }
                }

                LoadLocalFiles(SopFolderFullName);
                //Dispatcher.BeginInvoke(new Action(() =>
                //{
                //    if (pnlSopVideoList.Children.Count == 0) LoadLocalFiles(SopFolderFullName);
                //}));
            })).Start();

        }

        void LoadLocalFiles(string SopFolderFullName)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                pnlSopVideoList.Children.Clear();
            }));
            DirectoryInfo TheFolder = new DirectoryInfo(SopFolderFullName);
            foreach (FileInfo NextFile in TheFolder.GetFiles())
            {
                if (IsVideoType(NextFile.Name) || IsImageType(NextFile.Name) || IsPdfType(NextFile.Name))
                {
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        CheckBox chk = new CheckBox();
                        chk.Margin = new Thickness(5);
                        chk.FontSize = 28;
                        chk.Tag = NextFile.Name;
                        chk.Content = NextFile.Name;

                        chk.Checked += Chk_Checked;
                        chk.Unchecked += Chk_Unchecked;
                        pnlSopVideoList.Children.Add(chk);
                    }));
                }
            }
        }

        void ResetSopPlayer(string pathDir, CheckBox chk)
        {
            try
            {
                sopMediaPlayer.Ctlcontrols.stop();

                string path = @".\" + pathDir + "\\" + chk.Tag.ToString();
                string fname = chk.Tag.ToString();

                if (!System.IO.File.Exists(path))
                {
                    sopMediaPlayer.URL = "";
                    MessageDialogWnd.ShowDialog("操作指导", "本地无该文件");
                    //if (MessageDialogWnd.ShowDialog("操作指导", "本地无该文件，是否从服务器端下载？"))
                    //{
                    //    new Thread(new ThreadStart(delegate()
                    //    {
                    //        Dispatcher.BeginInvoke(new Action(() =>
                    //        {
                    //            chk.IsEnabled = false;
                    //            chk.Content = "..." + chk.Content.ToString();
                    //        }));
                    //        ftp.Download(System.AppDomain.CurrentDomain.BaseDirectory + pathDir, fname);
                    //        Dispatcher.BeginInvoke(new Action(() =>
                    //        {
                    //            chk.Content = chk.Content.ToString().Replace("...", "");
                    //            chk.IsEnabled = true;
                    //        }));
                    //    })).Start();
                    //}
                    chk.IsChecked = false;
                    return;
                }

                if (IsVideoType(path))
                {
                    sopMediaPlayer.URL = path;
                    sopMediaPlayer.settings.volume = 100;
                    sopMediaPlayer.settings.setMode("loop", true);//设置循环播放
                    sopMediaPlayer.Ctlcontrols.play();

                    svMediaPlayer.Visibility = System.Windows.Visibility.Visible;
                    svImage.Visibility = System.Windows.Visibility.Hidden;
                    //svPdfViewer.Visibility = System.Windows.Visibility.Hidden;
                    moonPdfPanel.Visibility = System.Windows.Visibility.Hidden;
                }
                else if (IsPdfType(path))
                {
                    //Dispatcher.Invoke(new Action(() =>
                    //{
                    //this.sopPdfViewer.LoadFromFile(path);
                    //}));
                    svMediaPlayer.Visibility = System.Windows.Visibility.Hidden;
                    svImage.Visibility = System.Windows.Visibility.Hidden;
                    //svPdfViewer.Visibility = System.Windows.Visibility.Visible;
                    moonPdfPanel.Visibility = System.Windows.Visibility.Visible;
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        //this.sopPdfViewer.LoadFromFile(path);
                        //Thread.Sleep(3000);
                        this.moonPdfPanel.OpenFile(path);
                    }));
                }
                else if (IsImageType(path))
                {
                    if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + path))
                    {
                        Uri uri = new Uri(AppDomain.CurrentDomain.BaseDirectory + path, UriKind.RelativeOrAbsolute);

                        imgSop.Source = new System.Windows.Media.Imaging.BitmapImage(uri);
                    }
                    else
                        imgSop.Source = null;

                    svMediaPlayer.Visibility = System.Windows.Visibility.Hidden;
                    svImage.Visibility = System.Windows.Visibility.Visible;
                    //svPdfViewer.Visibility = System.Windows.Visibility.Hidden;
                    moonPdfPanel.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    ShowMessage(this.lvMessage, "SOP文件格式不支持", true);
                }
            }
            catch (Exception ex)
            {
                ShowMessage(this.lvMessage, "SOP显示失败:" + ex.Message, true);
            }
        }

        private string ImageFileType = "BMP,JPG,JPEG,PNG,GIF";
        private string VideoFileType = "AVI,MP4,WMA,RMVB,3GP";
        private string PDFFileType = "PDF";
        bool IsVideoType(string path)
        {
            string fileType = path.Substring(path.LastIndexOf(".") + 1);
            if (VideoFileType.Contains(fileType.ToUpper()))
                return true;

            return false;
        }
        bool IsImageType(string path)
        {
            string fileType = path.Substring(path.LastIndexOf(".") + 1);
            if (ImageFileType.Contains(fileType.ToUpper()))
                return true;

            return false;
        }
        bool IsPdfType(string path)
        {
            string fileType = path.Substring(path.LastIndexOf(".") + 1);
            if (PDFFileType.Contains(fileType.ToUpper()))
                return true;

            return false;
        }

        void Chk_Checked(object sender, RoutedEventArgs e)
        {
            var chk = sender as CheckBox;

            if (chk != null)
            {
                foreach (CheckBox child in pnlSopVideoList.Children)
                {
                    if ((bool)child.IsChecked && child.Tag != chk.Tag)
                        child.IsChecked = false;
                }

                ResetSopPlayer(ConfigurationManager.AppSettings["SopFolder"].ToString(), chk);
            }
        }

        void Chk_Unchecked(object sender, RoutedEventArgs e)
        {
            var chk = sender as CheckBox;
            if (chk != null)
            {
                string fileName = chk.Tag.ToString();
                if (IsVideoType(fileName))
                {
                    sopMediaPlayer.Ctlcontrols.stop();
                }
                svMediaPlayer.Visibility = System.Windows.Visibility.Hidden;
                svImage.Visibility = System.Windows.Visibility.Hidden;
                svPdfViewer.Visibility = System.Windows.Visibility.Hidden;
            }
        }
        #endregion

        private void dataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.Header = e.Row.GetIndex() + 1;
        }

        private void dbgAllBarcode_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DataGrid dg = sender as DataGrid;
            selectedBarcode = dg.SelectedItem as BarcodeInfo;
            if (selectedBarcode != null)
                this.ctrNavBar.txtBarcode.Text = selectedBarcode.Barcode.ToUpper();
        }

        private void dbgAllBarcode_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {

        }


        //禁用主界面所有控件
        private void DisableUIControls()
        {
            this.ctrNavBar.txtBarcode.IsEnabled = false;
            this.btnLogin.IsEnabled = false;
           // this.btnMsgDevice.IsEnabled = false;
            this.btnAlarmRest.IsEnabled = false;
            this.btnOK.IsEnabled = false;
            this.btnNOK.IsEnabled = false;
            this.btnOnlineRepair.IsEnabled = false;
        }

        //启用主界面所有控件
        private void EnableUIControls()
        {
            //this.ctrNavBar.txtBarcode.IsEnabled = true;
            this.dbgAllBarcode.IsEnabled = true;
            this.btnLogin.IsEnabled = true;
            this.btnMsgDevice.IsEnabled = true;
            this.btnAlarmRest.IsEnabled = true;
            //this.btnOK.IsEnabled = UISession.ClientSetting.IsOKBtn ? true : false;
            //this.btnNOK.IsEnabled = UISession.ClientSetting.IsNOKBtn ? true : false;
            //this.btnOnlineRepair.IsEnabled = UISession.ClientSetting.IsRepairBtn ? true : false; 
        }

        //初始化条码列表列名
        private void InitDataGridColumn()
        {
            if (UISession.ClientSetting.IsDisplayScanNo)
            {
                this.dbgAllBarcode.Columns.Add(new DataGridTextColumn()
                {
                    Header = LanguageHelper.LoadStringFromResource("HEADER_SCANNO"),
                    Binding = new Binding("ScanNo"),
                    Width = 60,
                    IsReadOnly = false
                });
            }

            this.dbgAllBarcode.Columns.Add(new DataGridTextColumn()
            {
                Header = LanguageHelper.LoadStringFromResource("HEADER_BARCODE"),
                Binding = new Binding("Barcode"),
                Width = 400,
                IsReadOnly = false
            });

            if (UISession.ClientSetting.IsDisplayCodeLevel)
            {
                this.dbgAllBarcode.Columns.Add(new DataGridTextColumn()
                {
                    Header = LanguageHelper.LoadStringFromResource("HEADER_CODELEVEL"),
                    Binding = new Binding("CodeLevel"),
                    Width = 80,
                    IsReadOnly = false
                });
            }
            this.dbgAllBarcode.Columns.Add(new DataGridTextColumn()
            {
                Header = LanguageHelper.LoadStringFromResource("HEADER_PARTNO"),
                Binding = new Binding("PartNo"),
                Width = 80,
                IsReadOnly = false,
                Visibility = System.Windows.Visibility.Hidden
            });
            this.dbgAllBarcode.Columns.Add(new DataGridTextColumn()
            {
                Header = LanguageHelper.LoadStringFromResource("HEADER_TYPE"),
                Binding = new Binding("Type"),
                Width = 120,
                IsReadOnly = true,
                Visibility = Visibility.Collapsed
            });
            this.dbgAllBarcode.Columns.Add(new DataGridTextColumn()
            {
                Header = LanguageHelper.LoadStringFromResource("HEADER_STATE"),
                Binding = new Binding("State"),
                Width = 80,
                IsReadOnly = true,
                Visibility = Visibility.Collapsed
            });
            DataGridTextColumn dgtx = new DataGridTextColumn();
            dgtx.Header = LanguageHelper.LoadStringFromResource("HEADER_DATETIME");
            dgtx.Binding = new Binding("DateTime");
            dgtx.Width = 300;
            dgtx.IsReadOnly = true;
            dgtx.Binding.StringFormat = "yyyy-MM-dd HH:mm:ss";
            this.dbgAllBarcode.Columns.Add(dgtx);

            DataGridTemplateColumn tmpColumn = new DataGridTemplateColumn() { Header = LanguageHelper.LoadStringFromResource("HEADER_OPERATION") };
            DataTemplate tmp = new DataTemplate();
            //生成Button HorizontalAlignment="Left"  VerticalAlignment="Center" Content="Delete"  Height="30" Width="50"
            FrameworkElementFactory btn = new FrameworkElementFactory(typeof(Button));
            btn.SetValue(Button.ContentProperty, LanguageHelper.LoadStringFromResource("HEADER_DELETE"));
            btn.SetValue(Button.HorizontalAlignmentProperty, HorizontalAlignment.Left);
            btn.SetValue(Button.VerticalAlignmentProperty, VerticalAlignment.Center);
            btn.AddHandler(Button.ClickEvent, new RoutedEventHandler(DeleteButtonClick));
            tmp.VisualTree = btn;
            tmpColumn.CellTemplate = tmp;

            this.dbgAllBarcode.Columns.Add(tmpColumn);
        }

        //条码列表中的删除
        private void DeleteButtonClick(object sender, RoutedEventArgs e)
        {
            string strBarcode = ((BarcodeInfo)this.dbgAllBarcode.SelectedItem).Barcode;
            RemoveBarcodeCountCtr(strBarcode);
            List<BarcodeInfo> listBarcodeInfo = GetDataGridListBarcodeInfo();
            listBarcodeInfo.Remove(listBarcodeInfo.Find(x => x.Barcode == strBarcode));
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.dbgAllBarcode.ItemsSource = null;
                this.dbgAllBarcode.ItemsSource = listBarcodeInfo;
                if (listBarcodeInfo.Count > 0)
                    this.dbgAllBarcode.SelectedItem = listBarcodeInfo[0];
            }));
            clientSqlLite.DeleteBarcode(strBarcode);
        }

        //删除条码列表中的
        private bool RemoveBarcodeCountCtr(string barcode)
        {
            try
            {
                foreach (var ctrl in _barcodeCountCtrlList)
                {
                    if (ctrl.ScannedBarcode.Contains(barcode))
                    {
                        ctrl.RemoveBarcode(barcode);
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageDialogWnd.ShowDialog("", "RemoveBarcode error:" + ex.Message);
                Log4Helper.Error("RemoveBarcode error", ex);
            }
            return false;
        }

        private void InitUIDisplayItem()
        {
            //UISession.ClientSetting.IsUseProducePlanGrid
            this.gpbAllBarcode.Visibility = UISession.ClientSetting.IsUseProducePlanGrid ? Visibility.Collapsed : Visibility.Visible;

            // UISession.ClientSetting.IsGridPicUI
            this.miGridPic.Visibility = UISession.ClientSetting.IsGridPicUI ? Visibility.Visible : Visibility.Collapsed;

            //UISession.ClientSetting.IsProducePlanUI)
            this.miProducePlan.Visibility = UISession.ClientSetting.IsProducePlanUI ? Visibility.Visible : Visibility.Collapsed;

            if (UISession.ClientSetting.EnableIP1)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.IPDescription1;
                this.pnlDeviceSatus.Children.Add(ctrl);
                if (UISession.ClientSetting.IsScannerBtn)
                {
                    this.gpbScanner.Visibility = System.Windows.Visibility.Visible;
                }
            }
            if (UISession.ClientSetting.EnableIP2)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.IPDescription2;
                this.pnlDeviceSatus.Children.Add(ctrl);
                if (UISession.ClientSetting.IsScannerBtn)
                {
                    this.gpbScanner.Visibility = System.Windows.Visibility.Visible;
                }
            }
            if (UISession.ClientSetting.EnableIP3)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.IPDescription3;
                this.pnlDeviceSatus.Children.Add(ctrl);
                if (UISession.ClientSetting.IsScannerBtn)
                {
                    this.gpbScanner.Visibility = System.Windows.Visibility.Visible;
                }
            }
            if (UISession.ClientSetting.EnablePLC)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDescription;
                this.pnlDeviceSatus.Children.Add(ctrl);
            }

            if (UISession.ClientSetting.EnablePLCDB1)
            {
                //DeviceStatusControl ctrl = new DeviceStatusControl();
                //ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDBDescription1;
                //this.pnlDeviceSatus.Children.Add(ctrl);
            }
            if (UISession.ClientSetting.EnablePLCDB2)
            {
                //DeviceStatusControl ctrl = new DeviceStatusControl();
                //ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDBDescription2;
                //this.pnlDeviceSatus.Children.Add(ctrl);
            }
            if (UISession.ClientSetting.EnablePLCDB3)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDBDescription3;
                this.pnlDeviceSatus.Children.Add(ctrl);
            }
            if (UISession.ClientSetting.EnablePLCDB4)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDBDescription4;
                this.pnlDeviceSatus.Children.Add(ctrl);
            }
            if (UISession.ClientSetting.EnablePLCDB5)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDBDescription5;
                this.pnlDeviceSatus.Children.Add(ctrl);
            }
            if (UISession.ClientSetting.EnablePLCDB6)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDBDescription6;
                this.pnlDeviceSatus.Children.Add(ctrl);
            }
            if (UISession.ClientSetting.EnablePLCDB7)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = UISession.ClientSetting.PLCDBDescription7;
                this.pnlDeviceSatus.Children.Add(ctrl);
            }

            if (UISession.ClientSetting.COM_Enable)
            {
                DeviceStatusControl ctrl = new DeviceStatusControl();
                ctrl.blkDeviceName.Text = LanguageHelper.LoadStringFromResource("SCANNER");
                this.pnlDeviceSatus.Children.Add(ctrl);
            }
            //ACC server
            DeviceStatusControl statusCtr = new DeviceStatusControl();
            statusCtr.blkDeviceName.Text = LanguageHelper.LoadStringFromResource("LABEL_ACC_STATUS");
            this.pnlDeviceSatus.Children.Add(statusCtr);

        }

        //加载本地保存的条码        
        private void LoadDataGridBarcode()
        {
            DataTable dt = clientSqlLite.GetBarcode("OK");

            List<BarcodeInfo> listBarcode = new List<BarcodeInfo>();

            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.dbgAllBarcode.ItemsSource = dt.DefaultView;

                foreach (DataRowView dr in dt.DefaultView)
                {
                    listBarcode.Add(
                    new BarcodeInfo()
                    {
                        ScanNo = dr["ScanNO"].ToInt(),
                        Barcode = dr["Barcode"].ToString(),
                        CodeLevel = dr["CodeLevel"].ToString(),
                        PartNo = dr["PartNo"].ToString(),
                        Type = dr["Type"].ToString(),
                        State = dr["State"].ToString(),
                        DateTime = Convert.ToDateTime(dr["DateTime"])
                    });
                }
                this.dbgAllBarcode.ItemsSource = null;
                this.dbgAllBarcode.ItemsSource = listBarcode;
                if (listBarcode != null && listBarcode.Count > 0)
                {
                    this.dbgAllBarcode.SelectedItem = listBarcode[0];
                }
            }));
        }

        //关闭窗体并释放资源
        private bool CloseWindow()
        {
            try
            {
                var result = MessageDialogWnd.ShowDialog(
                LanguageHelper.LoadStringFromResource("TITLE_TOOLTIP"),
                LanguageHelper.LoadStringFromResource("MSG_ERR_EXIT_APPLICATION"));
                if (result)
                {
                    this.ctrNavBar.StopAlarm();
                    this.ctrNavBar.StopAlarmThread();

                    if (accSocketServer != null)
                    {
                        accSocketServer.AccSocketStop();
                    }

                    CloseClientPLC();

                    if (UISession.ClientSetting.COM_Enable && comScanner != null)
                    {
                        comScanner.Uninit();
                    }

                    //关闭状态栏检测线程
                    ClosePcClientThread();
                    Application.Current.Shutdown();
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch(Exception ex)
            {
                return false;
            }
        }

        private void CloseClientPLC()
        {
            if (plcProcess != null)
            {
                plcProcess.OnPlcTrigger -= new SiemensPlcProcess.PLCEventHandler(PlcProcessTrigger);
                plcProcess.OnConnected -= new SiemensPlcProcess.ConnectedHandler(UpdateDeviceStatus);
                plcProcess.Stop();
                plcProcess = null;
            }
        }

        private void ClosePcClientThread()
        {
            bIsRunning = false;
            if (_clientThread != null && _clientThread.ThreadState == ThreadState.Running)
            {
                _clientThread.Join(5000);
            }
            _clientThread = null;
        }

        //添加事件
        private void RegistCustomEvent()
        {
            this.ctrNavBar.txtBarcode.KeyDown += BarcodeTextKeyDown;
            this.ctrNavBar.txtBarcode.TextChanged += BarcodeTextChanged;
            this.MiExit.Click += ExitClick;
        }

        //输入条码按回车键
        private void BarcodeTextKeyDown(object sender, KeyEventArgs e)
        {
        }

        private void BarcodeTextChanged(object sender, TextChangedEventArgs e)
        {
            this.ctrNavBar.StopAlarm();
        }

        private void ExitClick(object sender, RoutedEventArgs e)
        {
            CloseWindow();
        }

        /// <summary>
        /// 重写父类方法，连接上ACC服务器后需要做的一些事
        /// </summary>
        public override void AccSocketServerConnected()
        {
            UpdateDeviceStatus(LanguageHelper.LoadStringFromResource("LABEL_ACC_STATUS"), true);
            ShowMessage(this.lvMessage, LanguageHelper.LoadStringFromResource("MSG_CONNECTED_ACC"), false);

            //连接PLC
            ConnectClientPLC();

            RefreshElementState();
        }

        

        /// <summary>
        /// 重写父类方法，与ACC断开连接
        /// </summary>
        public override void AccSocketServerDisconnected()
        {
            try
            {
                CloseClientPLC();
                ClosePcClientThread();
                UpdateDeviceStatus(LanguageHelper.LoadStringFromResource("LABEL_ACC_STATUS"), false);
                //Step1
                ShowMessage(this.lvMessage, LanguageHelper.LoadStringFromResource("MSG_DISCONNECTED_ACC"), true);

                //断连后需要将UISession中所有的缓存信息都清除，恢复到初始状态
                UISession.CurrentClient = null;
                UISession.CurrentPartType = null;
                UISession.CurrentOperator = null;
                UISession.CurrentPartTypeData = null;
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    _barcodeCountCtrlList.Clear();
                    pnlBarcodeCount.Children.Clear();
                    this.ctrNavBar.txtOperator.Text = string.Empty;
                    this.ctrNavBar.txtPartNO.Text = string.Empty;
                    this.ctrNavBar.txtShiftNO.Text = string.Empty;
                    this.ctrNavBar.txtStation.Text = string.Empty;
                    this.ctrNavBar.txtBarcode.Text = string.Empty;
                }));

                bIsAccConnected = false;
                RefreshElementState();
            }
            catch (Exception ex)
            {
                Log4Helper.Error(ex.StackTrace);
            }
        }

        /// <summary>
        /// 重写父类方法，接收到ACC换型通知时所做的事情
        /// </summary>
        public override void AccSocketServerChangeover(ClientPartType partType)
        {
            //不重复换型判断
            if (UISession.CurrentPartType != null && UISession.CurrentPartType.PartTypeId == partType.PartTypeId)
            {
                return;
            }
            if (partType == null)
            {
                return;
            }

            try
            {
                lock (_lockObj)
                {
                    if (partType.PartTypeId > 0)
                    {
                        //通知ACC进行换型
                        //根据PartType进行换型，获取相应的参数
                        UISession.CurrentPartType = partType;
                        string msg = String.Empty;
                        UISession.CurrentPartTypeData = accProcess.ChangeModel(partType.PartTypeId, out msg);
                        
                        if (!String.IsNullOrEmpty(msg))
                        {
                            if (UISession.CurrentPartType != null && UISession.CurrentPartType.PartTypeId != 0)
                            {
                                ShowMessage(this.lvMessage,
                                    String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("TITLE_ERR_CHANGEOVER"), msg),
                                    true);
                            }
                        }
                        else
                        {
                            ShowMessage(this.lvMessage, String.Format(LanguageHelper.LoadStringFromResource("MSG_CANGEOVER_COMPLETED"),
                            UISession.CurrentPartType.PartNo), false);

                            try
                            {
                                if (UISession.CurrentPartTypeData.PartTypeDatas != null &&
                                    UISession.CurrentPartTypeData.PartTypeDatas.Count > 0)
                                {
                                    SortedList listInt, listReal, listString;
                                    GetSendPartDataParam(UISession.CurrentPartTypeData.PartTypeDatas, out listInt, out listReal, out listString);
                                    Hashtable htPartTypeDataParam = new Hashtable();
                                    htPartTypeDataParam["N_INT"] = listInt;
                                    htPartTypeDataParam["N_REAL"] = listReal;
                                    htPartTypeDataParam["N_STRING"] = listString;
                                    if (plcProcess != null) plcProcess.WritePartTypeDataACC(htPartTypeDataParam, true);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log4Helper.Error(ex.StackTrace);
                            }

                            //换型完成后，填充界面信息
                            Dispatcher.BeginInvoke(new Action(() =>
                            {
                                if(plcProcess != null) plcProcess.WriteParttypeID(UISession.CurrentPartType.PartTypeId); 
                                this.ctrNavBar.txtPartNO.Text = partType.PartNo;
                            }));

                            //根据BOM生成当前的条码扫描计数表
                            FillBarcodeCountCtr();

                            //加载缓存的数据计数
                            LoadDataGridBarcodeCount();

                            //完成换型后，则重置一下界面按钮
                            RefreshElementState();

                            if (UISession.CurrentPartTypeData.ComponentSet != null)
                            {
                                FillLotTrack(UISession.CurrentPartTypeData.ComponentSet);
                            }
                            else
                            {
                                FillLotTrack(new List<ClientLotTrackItem>());
                            }

                            //显示工艺文件列表
                            List<MESWI> wis = new List<MESWI>();
                            if (UISession.CurrentPartTypeData.Reserved1 != null)
                            {
                                foreach (Object o in UISession.CurrentPartTypeData.Reserved1)
                                {
                                    //wis.Add((MESWI)o);
                                    var data = JsonHelper.ToObject<MESWI>(o.ToString());
                                    wis.Add(data);
                                }
                            }
                            FillWIS(wis);

                            //显示售后、质量问题列表
                            List<MESIssue> issues = new List<MESIssue>();
                            if (UISession.CurrentPartTypeData.Reserved2 != null)
                            {
                                foreach (Object o in UISession.CurrentPartTypeData.Reserved2)
                                {
                                    //issues.Add((MESIssue)o);
                                    var data = JsonHelper.ToObject<MESIssue>(o.ToString());
                                    issues.Add(data);
                                }
                            }
                            FillIssue(issues);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageDialogWnd.ShowDialog("", "ClientSocket_OnChangeover error:" + ex.Message);
                Log4Helper.Error("ClientSocket_OnChangeover error: ", ex);
            }
        }

        /// <summary>
        /// 重写父类方法，操作工登陆后填充页面
        /// </summary>
        public override void AccSocketServerOperatorChanged(ClientOperator oper)
        {
            UISession.CurrentOperator = oper;
            if (UISession.CurrentOperator != null)
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    this.ctrNavBar.txtOperator.Text = String.Format("{0}({1})",
                        UISession.CurrentOperator.Name,
                        UISession.CurrentOperator.OperatorId);
                }));
            }
            //操作工发生变化时，重置下按钮
            RefreshElementState();
        }

        /// <summary>
        /// 重写父类方式，更新设备状态
        /// </summary>
        /// <param name="strDeviceName"></param>
        /// <param name="bIsConnected"></param>
        public override void UpdateDeviceStatus(string strDeviceName, bool bIsConnected)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                foreach (UIElement ue in this.pnlDeviceSatus.Children)
                {
                    if (ue is DeviceStatusControl)
                    {
                        if (((DeviceStatusControl)ue).blkDeviceName.Text.ToString().ToUpper() == strDeviceName.ToUpper())
                        {
                            if (bIsConnected)
                            {
                                ((DeviceStatusControl)ue).txtDeviceStatusColor.Background = new SolidColorBrush(Colors.LawnGreen);
                            }
                            else
                            {
                                ((DeviceStatusControl)ue).txtDeviceStatusColor.Background = new SolidColorBrush(Colors.Red);
                            }
                        }
                    }
                }
            }));
        }

        //连接PLC后，判断本地是否有条码，启用判定按钮
        public override void PLCConnected()
        {
            try
            {
                if (accSocketServer.IsAccConnected && plcProcess != null && plcProcess.IsConnected && CheckScanFinished())
                    SetDecideBtn(true);
                else
                    SetDecideBtn(false);
            }
            catch(Exception ex)
            {
                Log4Helper.Error(ex.StackTrace);
            }
        }

        /// <summary>
        /// 根据一些条件判断控件Enable或Disable
        /// </summary>
        private void RefreshElementState()
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (!accSocketServer.GetAccSocketStatus() || UISession.CurrentPartType == null)
                {
                    DisableUIControls();
                }
                else
                {
                    EnableUIControls();
                    //控制登陆相关的两个按钮
                    if (UISession.ClientSetting.UseLineLeaderAssign)
                    {
                        //线长指派工位，Login按钮不可用
                        this.btnLogin.IsEnabled = false;
                    }

                    //如果时需要登陆的，则判断是否已经登陆
                    if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
                    {
                        //这时候扫描框是不能操作的
                        DisableUIControls();
                        this.btnLogin.IsEnabled = true;
                    }
                }
            }));
        }


        /// <summary>
        /// 填充条码计数面板
        /// </summary>
        private void FillBarcodeCountCtr()
        {
            Dispatcher.Invoke(new Action(() =>
            {
                pnlBarcodeCount.Children.Clear();
                //_barcodeCountCtrlList = new List<BarcodeCountControl>();
                _barcodeCountCtrlList.Clear();
                if (UISession.CurrentPartTypeData != null && UISession.CurrentPartTypeData.BOMItems != null)
                {
                    foreach (var bomItem in UISession.CurrentPartTypeData.BOMItems.ToArray().OrderBy(b => b.Qty))
                    {
                        BarcodeCountControl ctrl = new BarcodeCountControl(bomItem);
                        pnlBarcodeCount.Children.Add(ctrl);
                        _barcodeCountCtrlList.Add(ctrl);
                    }
                }
            }));
        }

        //加载缓存的数据计数
        private void LoadDataGridBarcodeCount()
        {
            ResetBarcodeCountCtr();

            Dispatcher.Invoke(new Action(() =>
            {
                foreach (BarcodeInfo bi in this.dbgAllBarcode.Items)
                {
                    AddBarcodeCountCtr(bi.Barcode);
                }
            }));
        }

        //清空计数
        private void ResetBarcodeCountCtr()
        {
            Dispatcher.Invoke(new Action(() =>
            {
                //重置条码计数器
                if (_barcodeCountCtrlList != null)
                {
                    foreach (var ctrl in _barcodeCountCtrlList)
                    {
                        ctrl.Reset();
                    }
                }
            }));
        }

        //启动PLC连接线程
        private void ConnectClientPLC()
        {
            if (UISession.ClientSetting.EnablePLC)
            {
                if (plcProcess == null)
                {
                    plcProcess = new SiemensPlcProcess(ClientPrint);
                    plcProcess.OnPlcTrigger += new SiemensPlcProcess.PLCEventHandler(PlcProcessTrigger);
                    plcProcess.OnConnected += new SiemensPlcProcess.ConnectedHandler(UpdateDeviceStatus);
                    plcProcess.OnPLCConnected += PLCConnected;

                    if (debugMode == "0")
                    {
                        plcProcess.InitPLC(0, UISession.ClientSetting.PLC_IP, UISession.ClientSetting.PLC_Port, UISession.ClientSetting.PLC_Rack, UISession.ClientSetting.PLC_Slot);
                    }
                    else
                    {
                        plcProcess.InitPLC(1, UISession.ClientSetting.PLC_IP, UISession.ClientSetting.PLC_Port, UISession.ClientSetting.PLC_Rack, UISession.ClientSetting.PLC_Slot);
                    }
                    plcProcess.PlcName = UISession.ClientSetting.PLCDescription;
                    plcProcess.PcSetting = UISession.ClientSetting;

                    plcProcess.CurrentClient = UISession.CurrentClient;
                    plcProcess.CurrentPartType = UISession.CurrentPartType;

                    plcProcess.IsRetryConnect = true;
                    if (!plcProcess.IsConnected)
                    {
                        plcProcess.Start();
                    }
                }
            }
        }

        public override void ClientPrint(string strData, string strMsg, bool isWarning)
        {
            ShowMessage(this.lvwMsgDevice, strData + " " + strMsg, isWarning);
        }

        //收到PLC的Load请求
        public override void LoadRequestPLC()
        {
            if (plcProcess != null)
            {
                ShowMessage(this.lvMessage, "Load Request", false);

                //获取工装号/托盘号
                string trayNo = plcProcess.GetTrayNo();
                bool bResLoad = PcClientLoad(trayNo);
                if (bResLoad && plcProcess != null)
                {
                    plcProcess.LoadSuccessfully();
                }
                else
                {
                    plcProcess.LoadFailed();
                }
            }
        }

        //bool? decided = null;
        bool isNG = false;
        UnloadVariable unloadNGData = null;
        //bool unloadRequested = false;
        //收到PLC的Unload请求
        public override void UnloadRequestPLC()
        {
            if (plcProcess != null)
            {
                //unloadRequested = true;
                ShowMessage(this.lvMessage, "Unload Request", false);

                //if (_barcodeCountCtrlList.Count <= 0)
                //{
                //    if (UISession.CurrentClient != null && UISession.CurrentClient.PartTypeId > 0 && UISession.PartTypeList != null)
                //    {
                //        var partType = UISession.PartTypeList.FirstOrDefault<ClientPartType>(p => p.PartTypeId == UISession.CurrentClient.PartTypeId);
                //        AccSocketServerChangeover(partType);
                //    }

                //    int index = 0;
                //    while (_barcodeCountCtrlList.Count <= 0 && bIsRunning)
                //    {
                //        Thread.Sleep(100);
                //        ++index;
                //        if (index > 100)
                //            break;
                //        if (index == 10)
                //            ShowMessage(this.lvMessage, LanguageHelper.LoadStringFromResource("WAITING_CHANGEOVER"), true);
                //    }
                //}

                if (_barcodeCountCtrlList.Count <= 0)
                {
                    ShowMessage(this.lvMessage, "型号没有在ACC服务端启动", true);
                    return;
                }

                if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
                {
                    ShowMessage(this.lvMessage, "操作工未登录", true);
                    return;
                }

                if (!UISession.ClientSetting.AutoUnload)
                {
                    ShowMessage(this.lvMessage, "非自动签出模式", true);
                    return;
                }

                //if (decided != null)//如果已判定给ACC发unload请求
                //{
                    List<string> barcodes = GetDataGridListBarcodeInfo().Select(p => p.Barcode).ToList();
                    if (isNG)//NOK
                    {
                        Decide(barcodes, 0, unloadNGData);
                    }
                    else//OK
                    {
                        Decide(barcodes, 1);
                    }
                //}
                //else
                //{
                //    ShowMessage(this.lvMessage, LanguageHelper.LoadStringFromResource("WAITING_DECIDE"), false);
                //}

            }
        }

        private bool PcClientLoad(string trayNo)
        {
            //if (_barcodeCountCtrlList.Count <= 0)
            //{
            //    if (UISession.CurrentClient != null && UISession.CurrentClient.PartTypeId > 0 && UISession.PartTypeList != null)
            //    {
            //        var partType = UISession.PartTypeList.FirstOrDefault<ClientPartType>(p => p.PartTypeId == UISession.CurrentClient.PartTypeId);
            //        AccSocketServerChangeover(partType);
            //    }

            //    int index = 0;
            //    while (_barcodeCountCtrlList.Count <= 0 && bIsRunning)
            //    {
            //        Thread.Sleep(100);
            //        ++index;
            //        if (index > 100)
            //            break;
            //        if (index == 10)
            //            ShowMessage(this.lvMessage, "等待客户端换型...", true);
            //    }
            //}

            if (_barcodeCountCtrlList.Count <= 0)
            {
                ShowMessage(this.lvMessage, "型号没有在ACC服务端启动", true);
                return false;
            }

            if (!UISession.ClientSetting.AutoLoad)
            {
                ShowMessage(this.lvMessage, "非自动签入模式", true);
                return false;
            }

            //显示扫描信息
            ShowMessage(this.lvMessage, String.Format(LanguageHelper.LoadStringFromResource("MSG_SCAN_TRAYNO"), trayNo), false);

            try
            {
                //清空条码列表
                ClearBarcode();
                //条码计数复位
                ResetBarcodeCountCtr();
                //unload变量复位
                ResetUnloadDec();


                ClientResponse accRes = SendLoadRequest(new List<string>() { trayNo });

                //      clientResponse.Data = new List<string>() { stnData.LastLoadUnit.UnitSN };
               //       clientResponse.Message = GetOrderInfo(stnData.LastLoadUnit.UnitSN);
                if (accRes.Result == true)
                {
                    //ACC Load成功
                    ShowMessage(this.lvMessage, LanguageHelper.LoadStringFromResource("MSG_ACC_LOAD_SUCCESS"), false);

                    //AccLoadData accLoadData = iPlant.Framework.ACC.WCF.Common.JsonHelper.ToObject<AccLoadData>(accRes.Data.ToString());

                    //模拟Load后ACC返回条码列表
                    List<string> lstBarcodes = JsonHelper.ToObject<List<string>>(accRes.Data.ToString());

                    List<BarcodeInfo> listBarcode = new List<BarcodeInfo>();
                    foreach (string barcode in lstBarcodes)
                    {
                        listBarcode.Add(
                            new BarcodeInfo
                            {
                                Barcode = barcode,
                                DateTime = DateTime.Now
                            });
                    }

                    foreach (BarcodeInfo barcode in listBarcode)
                    {
                        clientSqlLite.InsertBarcode(barcode, "OK");
                        if (!AddBarcodeCountCtr(barcode.Barcode))
                        {
                            Alarm(true);
                            ShowMessage(this.lvMessage, String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("TITLE_ERR_LOAD"),
                            LanguageHelper.LoadStringFromResource("MSG_ERR_BARCODE_ADD")), true);
                        }
                    }
                    LoadDataGridBarcode();//重新加载本地条码

                    // 首工序需要把写给PLC, 改成由ACC写入
                    //if (UISession.ClientSetting.IsFirstOP)
                    //{
                    //    Dispatcher.BeginInvoke(new Action(() =>
                    //    {
                    //        if (plcProcess != null)
                    //        {
                    //            if (this.ctrNavBar.txtBarcode.Text != "")
                    //            {
                    //                //把宇通内部码写给PLC
                    //                plcProcess.WriteInterSNToPlc(this.ctrNavBar.txtBarcode.Text);
                    //                ShowMessage(lvMessage, string.Format("宇通内部码:{0}", this.ctrNavBar.txtBarcode.Text), false);
                    //            }
                    //            if (!string.IsNullOrEmpty(accRes.Message))
                    //            {
                    //                string[] datas = accRes.Message.Split(',');
                    //               // if (datas.Length > 0)
                    //                    //plcProcess.WriteOrderNoToPlc(datas[0]); // 写入订单号
                    //                if (datas.Length > 1)
                    //                {
                    //                    plcProcess.WritePartNoToPlc(datas[1]);    // 写入产品型号
                    //                    ShowMessage(lvMessage, string.Format("产品型号:{0}", datas[1]), false);
                    //                }
                    //                if (datas.Length > 2)
                    //                {
                    //                    plcProcess.WritePlanCountToPlc(datas[2]); // 写入订单数量
                    //                    ShowMessage(lvMessage, string.Format("订单数量:{0}", datas[2]), false);
                    //                }
                    //            }
                    //        }
                    //        //if (string.IsNullOrEmpty(accRes.Message))
                    //        //{
                    //        //    //把国标码写给PLC
                    //        //    plcProcess.WriteGBSNToPlc(accRes.Message);
                    //        //}

                    //    }));
                      
                    //}
                }
                else
                {
                    //ACC Load没有成功，显示错误信息
                    ShowMessage(this.lvMessage, String.Format("{0}:{1}",
                            LanguageHelper.LoadStringFromResource("MSG_ACC_LOAD_FAILD"), accRes.Message), true);
                    return false;
                }
            }
            catch (Exception ex)
            {
                Log4Helper.Error("Scan Barcode TrayNo: ", ex);
                ShowMessage(this.lvMessage, ex.Message, true);
                return false;
            }
            return true;
        }


        public override void MaterialInRequestPLC(int portNo)
        {
            ShowMessage(this.lvMessage, string.Format("收到上料{0}信号", portNo), false);
            string fixtureNum = plcProcess.GetFixtureNum();
            ClientResponse res = accProcess.MaterialIn(fixtureNum, portNo, false);
            if (res.Result)
            {
                // port口为1,2,3,4、对应的bit位分别为0,2,4,6 
                int bSite = (Convert.ToInt32(portNo) - 1) * 2;
                plcProcess.MaterialInResult(bSite);
                ShowMessage(this.lvMessage, string.Format("上料{0}信号已通知MES", portNo), false);
            }
        }

        public override void MaterialOutRequestPLC(int portNo)
        {
            ShowMessage(this.lvMessage, string.Format("收到下料{0}信号", portNo), false);
            string fixtureNum = plcProcess.GetFixtureNum();
            ClientResponse res = accProcess.MaterialOut(fixtureNum, portNo);
            if (res.Result)
            {
                // port口为1,2,3,4、对应的bit位分别为1,3,5,7 
                int bSite = (Convert.ToInt32(portNo) - 1) * 2 + 1;
                plcProcess.MaterialOutResult(bSite);
                ShowMessage(this.lvMessage, string.Format("下料{0}信号已通知MES", portNo), false);
            }
            
        }

        public override void MaterialCoreInRequestPLC()
        {
            ShowMessage(this.lvMessage, string.Format("收到叫料信号"), false);
            ClientResponse res = accProcess.MaterialIn("", 1, true);
            if (res.Result)
            {
                int bSite = 0;
                plcProcess.MaterialCoreInResult(bSite);
                ShowMessage(this.lvMessage, string.Format("叫料信号已通知MES"), false);
            }
        }

        //清空条码列表
        private void ClearBarcode()
        {
            foreach (BarcodeInfo bi in this.dbgAllBarcode.Items)
            {
                clientSqlLite.DeleteBarcode(bi.Barcode);
            }
            LoadDataGridBarcode();
        }

        private void SetDecideBtn(bool enable)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.btnOK.IsEnabled = enable ? UISession.ClientSetting.IsOKBtn : enable;
                this.btnNOK.IsEnabled = enable ? UISession.ClientSetting.IsNOKBtn : enable;
                this.btnOnlineRepair.IsEnabled = enable ? UISession.ClientSetting.IsRepairBtn : enable;
            }));
        }

        //Unload请求ACC
        public bool PcClientUnload(List<string> barcodes, int result, UnloadVariable unloadData = null)
        {
            Log4Helper.Info("PcClientUnload Start");

            List<ClientProcData> lstProcessData = UISession.CurrentPartTypeData != null ? UISession.CurrentPartTypeData.ProcDatas.ToList() : null;

            try
            {
                if (lstProcessData != null && lstProcessData.Count > 0 && plcProcess != null)
                {
                    plcProcess.GetProcData(ref lstProcessData);
                }
                Log4Helper.Info("SendUnloadRequest Start");
                var unloadResult = SendUnloadRequest(barcodes, lstProcessData, unloadData, result, 0);
                Log4Helper.Info("SendUnloadRequest End");
                if (!unloadResult.Result)
                {
                    ShowMessage(this.lvMessage, String.Format("{0}:{1}",
                        LanguageHelper.LoadStringFromResource("MSG_ACC_UNLOAD_FAILD"), unloadResult.Message), true);
                    // UnloadRetry(GetScannedBarcodes(), lstProcessData, 1, unloadResult.Message);
                    return false;
                }
                else
                {
                    clientSqlLite.DeleteBarcode(barcodes);
                    ShowMessage(this.lvMessage, LanguageHelper.LoadStringFromResource("MSG_ACC_UNLOAD_SUCCESS"), false);
                    //重置界面元素
                    ResetCycle();
                    LoadDataGridBarcode();  //更新BarcodeList 数据
                }

                if (unloadResult.Data != null )
                {
                    List<ClientLotTrackItem> data = JsonHelper.ToObject<List<ClientLotTrackItem>>(unloadResult.Data.ToString());
                    FillLotTrack(data);
                }
            }
            catch (Exception ex)
            {
                MessageDialogWnd.ShowDialog("", "ACC Unload Error:" + ex.Message);
                Log4Helper.Error("ACC Unload Error: ", ex);
                return false;
            }
            Log4Helper.Info("PcClientUnload End");
            return true;
        }

        /// 检验条码是否已经扫描重复
        private bool IsBarcodeRepeat(string strBarcode)
        {
            List<string> listBarcode = GetScannedBarcodes();
            if (listBarcode.Contains(strBarcode))
            {
                Log4Helper.Debug(string.Format("{0} already in list, barcode repeated", strBarcode));
                clientSqlLite.DeleteBarcode(strBarcode);
                return false;
            }
            return false;
        }

        /// <summary>
        /// 获取一个循环中已经扫过的条码，防止重复输入
        /// </summary>
        /// <returns></returns>
        public override List<string> GetScannedBarcodes()
        {
            List<string> lstStrBarcode = new List<string>();
            DataTable dt = clientSqlLite.GetBarcode("OK");
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow row in dt.Rows)
                {
                    lstStrBarcode.Add(row["Barcode"].ToString());
                }
            }
            return lstStrBarcode;
        }

        private void Alarm(bool isAlarm)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (isAlarm)
                    this.ctrNavBar.StartAlarmThread();
                else
                    this.ctrNavBar.StopAlarm();
            }));
        }

        private bool AddBarcodeCountCtr(string barcode)
        {
            foreach (var ctrl in _barcodeCountCtrlList)
            {
                if (!ctrl.IsFull)
                {
                    return ctrl.AddBarcode(barcode);
                }
            }
            return false;
        }

        /// <summary>
        /// 检查一个扫描的Cycle是否已经完成
        /// </summary>
        /// <returns></returns>
        private bool CheckScanFinished()
        {
            if (_barcodeCountCtrlList.Count > 0)
            {
                foreach (var ctrl in _barcodeCountCtrlList.ToList())
                {
                    if (!ctrl.IsFull)
                    {
                        return false;
                    }
                }
                return true;
            }
            else
                return false;
        }

        //从ACC获取错误代码列表
        private List<ClientFailureWord> GetStatusWordList(ClientPartType partType)
        {
            if (UISession.CurrentPartType == null)
            {
                return new List<ClientFailureWord>();
            }
            AutoChangModelbyPartType(partType, this.lvMessage);
            List<ClientFailureWord> lstStatusWord = UISession.CurrentPartTypeData != null && UISession.CurrentPartTypeData.StatusBits.Count > 0 ? UISession.CurrentPartTypeData.StatusBits : new List<ClientFailureWord>();
            return lstStatusWord;
        }

        private void RemoveBarcodeList(List<string> ListStrBarcode)
        {
            foreach (string strBarcode in ListStrBarcode)
            {
                RemoveBarcodeCountCtr(strBarcode);
                clientSqlLite.DeleteBarcode(strBarcode);
            }

        }

        private List<BarcodeInfo> GetDataGridListBarcodeInfo()
        {
            List<BarcodeInfo> listBarcodeInfo = new List<BarcodeInfo>();
            foreach (BarcodeInfo item in this.dbgAllBarcode.Items)
            {
                listBarcodeInfo.Add(item);
            }
            return listBarcodeInfo;
        }

        /// <summary>
        /// 完成Load/Unload周期后，重置一些界面字段
        /// </summary>
        private void ResetCycle()
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                //重置条码列表和控件
                this.ctrNavBar.txtBarcode.Text = string.Empty;
                this.btnOK.IsEnabled = false;
                this.btnNOK.IsEnabled = false;
                this.btnOnlineRepair.IsEnabled = false;

            }));
            ResetBarcodeCountCtr();
            //停止报警闪烁
            Alarm(false);

            ResetUnloadDec();
        }

        private void ResetUnloadDec()
        {
            //decided = null;
            isNG = false;
            unloadNGData = null;
            //unloadRequested = false;
        }

        //从ACC获取错误代码列表
        private List<DefectData> GetStatusBitList(ClientPartType partType)
        {
            if (partType == null)
            {
                return new List<DefectData>();
            }
            //AutoChangModelbyPartType(partType, this.lvMessage);
            List<DefectData> lstDefectData = new List<DefectData>();
            List<ClientFailureWord> lstStatusWord = UISession.CurrentPartTypeData != null && UISession.CurrentPartTypeData.StatusBits.Count > 0 ? UISession.CurrentPartTypeData.StatusBits : new List<ClientFailureWord>();
            for (int i = 0; i < lstStatusWord.Count; i++)
            {
                if (lstStatusWord[i].StatusBits != null)
                {
                    foreach (ClientFailureBit item in lstStatusWord[i].StatusBits)
                    {
                        DefectData defectData = new DefectData();
                        defectData.StatusName = lstStatusWord[i].Name;
                        defectData.IsChecked = false;
                        defectData.InBit = item.Bit;
                        if (item.Description.IndexOf(':') > -1)
                        {
                            defectData.DefectCode = item.Description.Substring(0, item.Description.IndexOf(':') == -1 ? 0 : item.Description.IndexOf(':'));
                            defectData.DefectDescription = item.Description.Substring(item.Description.IndexOf(':') + 1, item.Description.Length - item.Description.IndexOf(':') - 1);
                            lstDefectData.Add(defectData);
                        }
                    }
                }
            }
            return lstDefectData;
        }

        //填充物料信息
        public override void FillLotTrack(List<ClientLotTrackItem> lots)
        {
            //if (this.gridComp.ItemsSource != null)
            //{
            //    List<ClientLotTrackItem> source = (List<ClientLotTrackItem>)this.gridComp.ItemsSource;
                
            //    foreach (ClientLotTrackItem item in source)
            //    {
            //        if (lots != null && lots.Count > 0)
            //        {
            //            if (!lots.Exists(x => x.ItemPartNo == item.ItemPartNo))
            //            {
            //                lots.Add(item);
            //            }
            //        }
            //        else
            //        {
            //            if (lots == null)
            //                lots = new List<ClientLotTrackItem>();
            //            lots.Add(item);
            //        }
                    
            //    }
            //}
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.gridComp.ItemsSource = null;
                this.gridComp.ItemsSource = lots;
            }));
        }

        //填充工艺文件
        public override void FillWIS(List<MESWI> wis)
        {
            //从远程FTP加载工艺文件列表
            AddSopVideoList(wis);
        }

        //填充售后，质量问题
        public override void FillIssue(List<MESIssue> issues)
        {
            //MESIssue t1 = new MESIssue();
            //t1.op_code = "L1M03030";
            //t1.op_name = "预埋钢扎带";
            //t1.cell_code = "L1M13031";
            //t1.cell_name = "预埋钢扎带";
            //t1.issue_des = "质量问题";
            //issues.Add(t1);
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.gridAfterSale.ItemsSource = null;
                this.gridAfterSale.ItemsSource = issues;
            }));
        }

        /// <summary>
        /// 把国标码写给PLC
        /// </summary>
        /// <param name="issues"></param>
        public override void ReceivedGBSN(string gbsn)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (plcProcess != null)
                {
                    plcProcess.WriteGBSNToPlc(gbsn);
                    ShowMessage(lvMessage, string.Format("国标码:{0}", gbsn), false);

                }
            }));
        }

        //填充班次信息
        public override void FillShift(ClientShiftCfg shift)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.ctrNavBar.txtShiftNO.Text = shift == null ? "" : string.Format("{0}({1})", shift.ShiftName, shift.ShiftOrder);
            }));
        }

        private void txtBarcode_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && txtBarcode.Text != "")
            {
                HandleScanMaterial();
            }
        }

        private void HandleScanMaterial()
        {
            // 二维码格式如下:
            // 802026/10/2119-00039/20190703/K/01/211900039C02697030001/*
            // 0000/50/2134-00054/20190703/K/01/*/20190703
            // 5205/255000/9301-05142/20190703/K/55/*/20190703
            // 2286/36/9304-02960/20190703/K/00/*/*
            // 含义：供应商代码/数量/物料号/生产日期/寄售/版本号/批次号/有效期至
            //  所有物料二维码信息遵循以上规则：
            // 1、  不同的物料物料号不同；相同的物料物料号保持不变
            // 2、  不同的物料存在信息完整现象，如：有的物料有批次号没有生产日期、有的物料有生产日期没有有效日期至等，没有的信息用*代替；
            // 3、  物料追溯信息以批次号为准，没有批次号的以生产日期为准。

            ShowMessage(this.lvMessage, String.Format("物料二维码:{0}", txtBarcode.Text), false);
            string[] data = txtBarcode.Text.Split('/');
            if (data != null && data.Length == 8)
            {
                string ItemPartNo = data[2];            // 物料号
                string Lot = data[6];                   // 批次号
                string USN = "";
                string Qty = data[1];                   // 数量
                string SLot = "";

                // 如果批次号为*号、表示该物料没有批次号。把生产日期作为批次号
                if (data[6] == "*")
                {
                    Lot = data[3];                      // 生产日期
                }

                ClientResponse res = accProcess.LotChange(ItemPartNo, Lot, USN, SLot, Qty);
                if (res.Result)
                {
                    this.txtBarcode.Text = "";
                    string msg;
                    ShowMessage(this.lvMessage, String.Format("扫料成功:物料号 = {0},批次号 ={1},数量 = {2}", ItemPartNo, Lot, Qty), false);
                }
                else
                {
                    this.txtBarcode.SelectAll();
                    ShowMessage(this.lvMessage, String.Format("扫料失败:{3} 物料号 = {0},批次号 ={1},数量 = {2}", ItemPartNo, Lot, Qty, res.Message), true);
                }
            }
            else
            {
                ShowMessage(this.lvMessage, String.Format("物料二维码格式错误、请确认二维码内容"), true);
            }
        }

        /// <summary>
        /// 整型地址索引样式
        /// </summary>
        public Regex INT_PATTERN = new Regex("INT\\[(\\d+)\\]", RegexOptions.IgnoreCase);
        /// <summary>
        /// 浮点型地址索引样式
        /// </summary>
        public Regex REAL_PATTERN = new Regex("REAL\\[(\\d+)\\]", RegexOptions.IgnoreCase);
        /// <summary>
        /// 字符串型地址索引样式
        /// </summary>
        public Regex STRING_PATTERN = new Regex("STRING\\[(\\d+)\\]", RegexOptions.IgnoreCase);
        protected virtual void GetSendPartDataParam(List<ClientParttypeData> lsParttypeData, out SortedList listInt, out SortedList listReal, out SortedList listString)
        {
            listInt = new SortedList();
            listReal = new SortedList();
            listString = new SortedList();
            string address;
            Match match;
            int num;
            Regex regex = null;
            SortedList list = null;
            foreach (ClientParttypeData cfg in lsParttypeData)
            {
                address = cfg.Address;
                if (cfg.ValueType == "PLC_INT")
                {
                    regex = INT_PATTERN;
                    list = listInt;
                }
                else if (cfg.ValueType == "PLC_REAL")
                {
                    regex = REAL_PATTERN;
                    list = listReal;
                }
                else if (cfg.ValueType == "PLC_STRING")
                {
                    regex = STRING_PATTERN;
                    list = listString;
                }
                else
                {
                    continue;
                }
                if (address.ToUpper().IndexOf("INT") != -1)
                {
                    regex = INT_PATTERN;
                    list = listInt;
                }
                else if (address.ToUpper().IndexOf("REAL") != -1)
                {
                    regex = REAL_PATTERN;
                    list = listReal;
                }
                else
                {
                    continue;
                }
                match = regex.Match(address.ToUpper());
                if (match.Success)
                {
                    num = int.Parse(match.Groups[1].Value);
                    if (list.Contains(num))
                    {
                        list[num] = cfg.Value;
                    }
                    else
                    {
                        list.Add(num, cfg.Value);
                    }
                    //if (regex == STRING_PATTERN)
                    //{
                    //    list[num] = cfg.ValueStr;
                    //}
                }
            }
        }

        private void tiSop_MouseEnter(object sender, MouseEventArgs e)
        {
            string SopFolderFullName = System.AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["SopFolder"].ToString();
            LoadLocalFiles(SopFolderFullName);
        }
    }
}
